package com.iflytek.aiui.uartkit.core;

/**
 * Copyright (c) 2017, SuZhou CsjBot. All Rights Reserved.
 * www.csjbot.com
 * <p>
 * Created by 浦耀宗 at 2017/02/09 0009-14:06.
 * Email: puyz@csjbot.com
 */
import android.content.Context;

import com.csjbot.csjbase.log.Csjlogger;
import com.upcontrol.uartagent.core.inter.DataReceive;
import com.usb2uartagent.IUARTConnectorHelper;
import com.usb2uartagent.Usb2UartagentSingleManager;

import tw.com.prolific.driver.pl2303.PL2303Driver;

public class UsbUARTConnectorHelper implements IUARTConnectorHelper, Usb2UartagentSingleManager.DataHandler {
    private static final String TAG = "UsbUARTConnectorHelper";

    public static final int RECV_BUF_LEN = 12;
    public static final int MSG_NORMAL_LEN = 4;
    public static final int MSG_EXTRA_LEN = 8;
    public static final int PACKET_LEN_BIT = 4;
    public static final byte SYNC_HEAD = (byte) 0xa5;
    public static final byte SYNC_HEAD_SECOND = (byte) 0x01;

    private int recv_index = 0;
    private byte recv_buf[] = new byte[RECV_BUF_LEN];
    private int big_buf_len = 0;
    private int big_buf_index = 0;
    private byte[] big_buf = null;
    public static boolean bHandleMsgOk;

    public int init(Context context, String device, int speed) {
        Usb2UartagentSingleManager.getInstance().setDataHandle(this);
//        Usb2UartagentManager.getInstance().setDataHandle(Usb2UartagentManager.AIUI_TYPE, this);
        return Usb2UartagentSingleManager.getInstance().init(context, PL2303Driver.BaudRate.B115200);
    }


    public int send(byte[] data) {
        return Usb2UartagentSingleManager.getInstance().sendData(data);
//        return Usb2UartagentManager.getInstance().sendData(Usb2UartagentManager.AIUI_TYPE, data);
    }

    public void destroy() {
//        Usb2UartagentManager.getInstance().releaseByType(Usb2UartagentManager.AIUI_TYPE);
    }

    @Override
    public void setDataReceive(DataReceive receive) {

    }

    @Override
    public void handleData(byte[] data, int length) {
        handleAIUIMsg(data, length);
    }

    private void handleAIUIMsg(final byte[] msg, final int msglen) {
        Csjlogger.debug("USB uart recv: " + msglen);

        if (big_buf == null && recv_index + msglen >= 2) {
            if (recv_index == 0) {
                if (msg[0] != SYNC_HEAD || msg[1] != SYNC_HEAD_SECOND) {
                    Csjlogger.debug("recv data not SYNC HEAD, drop");
                    return;
                }
            } else if (recv_index == 1) {
                if (recv_buf[0] != SYNC_HEAD || msg[0] != SYNC_HEAD_SECOND) {
                    Csjlogger.debug("recv data not SYNC HEAD, drop");
                    recv_index = 0;
                    return;
                }
            }
        }

        int copy_len;
        if (big_buf != null) {
            copy_len = big_buf_len - big_buf_index < msglen ? big_buf_len - big_buf_index : msglen;
            System.arraycopy(msg, 0, big_buf, big_buf_index, copy_len);
            big_buf_index += copy_len;
            if (big_buf_index < big_buf_len)
                return;
        } else {
            copy_len = RECV_BUF_LEN - recv_index < msglen ? RECV_BUF_LEN - recv_index : msglen;
            System.arraycopy(msg, 0, recv_buf, recv_index, copy_len);
            if ((recv_index + copy_len) > PACKET_LEN_BIT) {
                int content_len = ((recv_buf[PACKET_LEN_BIT] & 0xff) << 8) | (0xff & recv_buf[PACKET_LEN_BIT - 1]);
                if (content_len < 0) {
                    Csjlogger.error(TAG, "content_len is " + content_len);
                }
                if (content_len != MSG_NORMAL_LEN) {
                    big_buf_index = 0;
                    big_buf_len = content_len + MSG_EXTRA_LEN;
                    big_buf = new byte[big_buf_len];
                    System.arraycopy(recv_buf, 0, big_buf, 0, recv_index);
                    big_buf_index += recv_index;
                    recv_index = 0;
                    handleAIUIMsg(msg, msglen);
                    return;
                }
            }
            recv_index += copy_len;
            if (recv_index < RECV_BUF_LEN) return;
        }

        byte[] rec_data;
        if (big_buf != null) {
            rec_data = new byte[big_buf_len];
            System.arraycopy(big_buf, 0, rec_data, 0, big_buf_len);
            big_buf_len = 0;
            big_buf_index = 0;
            big_buf = null;
            Csjlogger.debug("handle a big buf over!");
        } else {
            rec_data = new byte[RECV_BUF_LEN];
            System.arraycopy(recv_buf, 0, rec_data, 0, RECV_BUF_LEN);
            recv_index = 0;
            Csjlogger.debug("handle a normal buf over!");
        }

        onDataRecevie(rec_data);

        if (copy_len < msglen) {
            Csjlogger.debug("multi msg in one stream left :" + (msglen - copy_len) + " byte");
            byte[] msgTmp = new byte[msglen - copy_len];
            System.arraycopy(msg, copy_len, msgTmp, 0, msglen - copy_len);
            handleAIUIMsg(msgTmp, msglen - copy_len);
        }
    }

    @Override
    public void onDataRecevie(byte[] data) {
        bHandleMsgOk = true;

        UARTManager.getManager().onReceive(data);
    }
}
